﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Having.Site.Base
{
    /// <summary>
    /// 线程Task的同时执行的数量控制(重要的，需要快速响应的，不安全的)
    /// </summary>
    public static class LimitTask
    {
        static int CurTaskCount = 0;//当前线程数
        static Queue<Task> list = new Queue<Task>();
        static object o = new object();
        static object c = new object();
        /// <summary>
        /// 添加一个异步方法，等到处理
        /// </summary>
        /// <param name="t"></param>
        public static void Add(Task t) {
            lock(o)
            {
                list.Enqueue(t);
            }
        }
        /// <summary>
        /// 添加一个方法，等到异步处理
        /// </summary>
        /// <param name="t"></param>
        public static void Add(Action t)
        {
            lock (o)
            {
                list.Enqueue(Task.Run(t));
            }
        }
        /// <summary>
        /// 开始操作，该方法必须在global的Application_start中，并且需要线程来操作
        /// </summary>
        public static bool Working()
        {
            var CurTaskmax = list.Count>5?5: list.Count;
            if (CurTaskCount < CurTaskmax && list.Count > 0)
            {
                BeginWork();
            }
            if (CurTaskCount == 0 || list.Count == 0)
            {
                CurTaskCount = 0;
                return false;
            }
            return true;
        }

        static void BeginWork()
        {
            if (list.Count > 0)
            {
                CurTaskCount++;
                WorkBack();
            }
        }
        static void WorkBack() {
            if (list.Count > 0)
            {
                Task t;
                lock (c)
                {
                    t= list.Dequeue(); ;
                }
                if ((int)t.Status < 3)
                {
                    try
                    {
                        t.Start();
                    }
                    catch
                    { }
                }
                t.ContinueWith(m => WorkBack());
            }
            else
            {
                if (CurTaskCount > 0)
                {
                    CurTaskCount--;
                }
            }
        }
    }
}
